package com.zlzlib.liblayoutmanager;

import android.graphics.Rect;
import android.view.View;
import android.widget.LinearLayout;

import androidx.recyclerview.widget.RecyclerView;

/**
 * @Desc: LayoutManagers 的助手类，用于根据视图的方向抽象测量值。 围绕视图边界和具有边距和装饰的子测量的调用。
 * @Copyright:
 * @DateTime: 2021/8/12 10:01
 * @Author zlz
 * @Version 1.0
 */
public abstract class OrientationUtils {

    private static final int INVALID_SIZE = Integer.MIN_VALUE;

    protected final RecyclerView.LayoutManager mLayoutManager;

    protected final Rect mTmpRect = new Rect();

    private int mLastTotalSpace = INVALID_SIZE;

    protected OrientationUtils(RecyclerView.LayoutManager mLayoutManager) {
        this.mLayoutManager = mLayoutManager;
    }

    /**
     * 如果状态不是预布局，则在 onLayout 方法完成后调用此方法。
     * 此方法记录 布局边界 的信息，这些信息可能在下一个布局计算中有用。
     */
    public void onLayoutComplete() {
        mLastTotalSpace = getTotalSpace();
    }

    /**
     * @return 当前总空间与先前布局的总空间之间的差值
     */
    public int getTotalSpaceChange() {
        return INVALID_SIZE == mLastTotalSpace ? 0 : getTotalSpace() - mLastTotalSpace;
    }

    /**
     * 计算当前传入的子view 的起始坐标大小 包含了偏移Margin 和 内边距
     *
     * @param view
     * @return
     */
    public abstract int getDecoratedStart(View view);

    /**
     * 计算当前传入的子view 的终点坐标大小 包含了偏移Margin 和 内边距
     *
     * @param view
     * @return
     */
    public abstract int getDecoratedEnd(View view);

    /**
     * 通过 RecyclerView.LayoutManager#getTransformedBoundingBox(View, boolean, Rect)
     * 计算终点位置
     *
     * @param view
     * @return
     */
    public abstract int getTransformedEndWithDecoration(View view);

    /**
     * 通过 RecyclerView.LayoutManager#getTransformedBoundingBox(View, boolean, Rect)
     * 计算起点位置
     *
     * @param view
     * @return
     */
    public abstract int getTransformedStartWithDecoration(View view);

    /**
     * 返回当前view所占的空间  水平为宽度  竖直为高度
     *
     * @param view
     * @return
     */
    public abstract int getDecoratedMeasurement(View view);

    /**
     * 返回当前view所占的空间  水平为高度   竖直为宽度
     *
     * @param view
     * @return
     */
    public abstract int getDecoratedMeasurementInOther(View view);

    /**
     * 获得可以绘制空间的起始点
     *
     * @return
     */
    public abstract int getStartAfterPadding();

    /**
     * 获得可以绘制空间的终点
     *
     * @return
     */
    public abstract int getEndAfterPadding();

    /**
     * 获得整体的空间大小  水平为宽度 数值为高度
     *
     * @return
     */
    public abstract int getEnd();

    /**
     * 整体末尾的padding
     *
     * @return
     */
    public abstract int getEndPadding();

    /**
     * 获得当前总空间大小  去除Padding 水平为宽度  竖直为高度
     *
     * @return
     */
    public abstract int getTotalSpace();

    /**
     * 获得当前总空间大小 去除Padding  水平为高度   竖直为宽度
     *
     * @return
     */
    public abstract int getTotalSpaceInOther();

    /**
     * 当前测量规范模式。 水平为宽度   竖直为高度
     *
     * @return
     * @see View.MeasureSpec
     * @see RecyclerView.LayoutManager#getWidthMode()
     * @see RecyclerView.LayoutManager#getHeightMode()
     */
    public abstract int getMode();

    /**
     * 当前测量规范模式。水平为高度   竖直为宽度
     *
     * @return
     * @see View.MeasureSpec
     * @see RecyclerView.LayoutManager#getWidthMode()
     * @see RecyclerView.LayoutManager#getHeightMode()
     */
    public abstract int getModeInOther();

    public static OrientationUtils createOrientationUtils(RecyclerView.LayoutManager layoutManager, int orientation) {
        switch (orientation) {
            case LinearLayout.HORIZONTAL:
                return new OrientationHorizontalUtils(layoutManager);
            case LinearLayout.VERTICAL:
                return new OrientationVerticalUtils(layoutManager);
        }
        throw new IllegalArgumentException("invalid orientation");
    }
}
